home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-04 | 24.7 KB | 832 lines | [TEXT/MMCC] |
- /*================================================================================
- SaveWindows.cp
-
- ©1994 Greg Anderson
- greggor@apple.com
-
- Send events to the Finder
-
- ================================================================================*/
- #include "SaveWindows.h"
- #include "AppleEventUtilities.h"
- #include "AERegistry.h"
- #include "AEObjects.h"
- #include "FinderRegistry.h"
-
- #ifndef Exceptions_h
- #include "Exceptions.h"
- #endif
-
- //----------------------------------------------------------------------------------------
- // FindPSNbyTypeAndSig:
- //
- // Find the PSN of some process, given its type and creator
- //----------------------------------------------------------------------------------------
- void FindPSNbyTypeAndSig(ProcessSerialNumber* psn, OSType type, OSType sig)
- {
- ProcessInfoRec theProc;
-
- //
- // Start out with kNoProcess
- //
- psn->highLongOfPSN = 0;
- psn->lowLongOfPSN = kNoProcess;
-
- //
- // Initialize fields in the ProcessInfoRec,
- // or we'll have memory hits in random locations
- //
- theProc.processInfoLength = sizeof( ProcessInfoRec );
- theProc.processName = nil;
- theProc.processAppSpec = nil;
- theProc.processLocation = nil;
-
- while(true)
- {
- OSErr theErr;
-
- //
- // Keep looking for the process until we find it
- //
- FailErr(GetNextProcess(psn));
-
- //
- // Is the current process the one we're looking for?
- //
- FailErr(GetProcessInformation(psn, &theProc));
- if( (theProc.processType == type ) && (theProc.processSignature == sig) )
- break;
- }
- } // FindPSNbyTypeAndSig
-
- //----------------------------------------------------------------------------------------
- // GetAddressOfFinder:
- //
- // Generate an address for the Finder on this machine
- //----------------------------------------------------------------------------------------
- TDescriptor GetAddressOfFinder()
- {
- ProcessSerialNumber finderPSN;
- TDescriptor finderAddressDescriptor;
-
- //
- // Find the Finder's PSN
- //
- FindPSNbyTypeAndSig(&finderPSN, 'FNDR', 'MACS');
-
- //
- // Copy the target ID into a descriptor
- //
- finderAddressDescriptor.MakeProcessSerialNumber(finderPSN);
-
- return finderAddressDescriptor;
- } // GetAddressOfFinder
-
- //----------------------------------------------------------------------------------------
- // MakeSpecifierForSelection
- //----------------------------------------------------------------------------------------
- TDescriptor MakeSpecifierForSelection()
- {
- TDescriptor selectionSpecifier;
- TDescriptor nullDescriptor;
- TDescriptor keyData;
-
- //
- // Make a descriptor whose type is 'typeType' and whose
- // contents are 'pSelection' (defined in FinderRegistry.h).
- // This descriptor specifies the property of the null container
- // that we are interested in--in this case, the selection.
- //
- keyData.MakeDescType(pSelection);
-
- //
- // Make an object specifier for "selection of <null container>".
- // The object specifier will contain the following:
- //
- // Desired class: cProperty Object specifiers that
- // specify properties always
- // have a desired class of cProperty
- //
- // Container: null A null descriptor specifies the
- // null container. Object specifiers
- // almost always terminate with the
- // null descriptor, the only exceptions
- // being specifiers used to support
- // "paste reference," which terminate
- // in the PSN of the process that
- // generated them, and object specifiers
- // contained in test descriptors
- // (found in "whose" clauses) that
- // often terminate with "object being
- // examined".
- //
- // Key form: formPropertyID Object specifiers that specify properties
- // always have a key form of formPropertyID.
- //
- // Key data: typeType / The key data descriptor of a property
- // pSelection must always be of type typeType; in
- // our case, it is a descriptor that
- // contains pSelection (built above).
- //
- // We pass 'true' to MakeObjectSpecifier, so it will always dispose its inputs.
- // If we passed in 'false', we would have to dispose of the keyData descriptor
- // ourselves.
- //
- selectionSpecifier.MakeObjectSpecifier( cProperty,
- nullDescriptor,
- formPropertyID,
- keyData,
- true);
-
- return selectionSpecifier;
- } // MakeSpecifierForSelection
-
- //----------------------------------------------------------------------------------------
- // MakeSpecifierForIndexedItem
- //----------------------------------------------------------------------------------------
- TDescriptor MakeSpecifierForIndexedItem(DescType desiredClass, long index, TDescriptor ofSpecifier)
- {
- TDescriptor resultSpecifier;
- TDescriptor keyData;
-
- //
- // Make a descriptor whose type is 'typeLongInteger' and whose
- // contents is the index passed in.
- //
- keyData.MakeLong(index);
-
- //
- // Make an object specifier for "<<class desiredClass>> index of <ofSpecifier>".
- // The object specifier will contain the following:
- //
- // Desired class: desiredClass The class of the object being
- // referenced examples include cWindow,
- // cObject, cDisk, cAliasFile, and
- // many others
- //
- // Container: ofSpecifier Object specifiers are defined
- // recursively
- //
- // Key form: formAbsolutePosition This indicates that we are accessing
- // the 'index'th item of the container.
- // Another choice would be formName, in
- // which case the key data would
- // contain the name of the object being
- // referenced.
- //
- // Key data: typeLongInteger / formAbsolutePosition implies that
- // 'index' the key data will be an integer
- //
- // We pass 'false' to MakeObjectSpecifier, so our inputs are not disposed
- // (we want to keep 'ofSpecifier' around). Because we didn't ask MakeObjectSpecifier
- // to delete our inputs, we'll have to delete the key data ourselves
- //
- resultSpecifier.MakeObjectSpecifier( desiredClass,
- ofSpecifier,
- formAbsolutePosition,
- keyData,
- false);
- keyData.Dispose();
-
- return resultSpecifier;
- } // MakeSpecifierForSelection
-
- //----------------------------------------------------------------------------------------
- // MakeSpecifierForFrontWindow
- //----------------------------------------------------------------------------------------
- TDescriptor MakeSpecifierForFrontWindow()
- {
- TDescriptor nullDescriptor;
-
- return MakeSpecifierForIndexedItem(cWindow, 1, nullDescriptor);
- }
-
- //----------------------------------------------------------------------------------------
- // MakeSpecifierForPropertyOfSpecifier:
- //
- // This function makes an object specifier for "property of <<specifier provided>>"
- //----------------------------------------------------------------------------------------
- TDescriptor MakeSpecifierForPropertyOfSpecifier(DescType property, TDescriptor ofSpecifier)
- {
- TDescriptor specifier;
- TDescriptor keyData;
- OSErr err = noErr;
-
- //
- // Make a descriptor whose type is 'typeType', and whose
- // contents are the property passed into this function.
- //
- keyData.MakeDescType(property);
-
- Try
- {
- //
- // The next object specifier we make also specifies a property, so it
- // will look very similar to the one we built above:
- //
- // Desired class cProperty Required to specify a property.
- //
- // Container "ofSpecifier" We are making a specifier for
- // "property of <ofSpecifier>", so clearly
- // our container must be the
- // object specifier passed in.
- //
- // Key form: formPropertyID Required to specify a property.
- //
- // Key data typeType / As before, the key data descriptor
- // property is typeType, and contains the property ID
- // that we wish to specify.
- //
- // This time we pass 'false' to MakeObjectSpecifier so that it will NOT dispose
- // of its inputs when it is done. Doing this leaves the keyData and ofSpecifier
- // descriptors intact; we dispose of the key data, but leave the specifier that
- // was passed into this function the responsibility of the caller.
- //
- specifier.MakeObjectSpecifier( cProperty,
- ofSpecifier,
- formPropertyID,
- keyData,
- false);
- keyData.Dispose();
- }
- Catch(err)
- {
- //
- // Note that 'MakeObjectSpecifier' might fail (out of memory, for example),
- // so we must catch failures to dispose of the key data descriptor if necessary.
- //
- keyData.Dispose();
- Throw(err);
- }
-
- return specifier;
- } // MakeSpecifierForPropertyOfSpecifier
-
- //----------------------------------------------------------------------------------------
- // MakeSpecifierForPropertyOfSelection:
- //
- // This function makes an object specifier for "property of selection"
- //----------------------------------------------------------------------------------------
- TDescriptor MakeSpecifierForPropertyOfSelection(DescType property)
- {
- TDescriptor specifier;
- TDescriptor selectionSpecifier;
- TDescriptor keyData;
- OSErr err = noErr;
-
- //
- // Build an object specifier for "selection of <null container>"
- //
- selectionSpecifier = MakeSpecifierForSelection();
-
- Try
- {
- //
- // Next, make a specifier for "property of selection"
- //
- specifier = MakeSpecifierForPropertyOfSpecifier(property, selectionSpecifier);
- selectionSpecifier.Dispose();
- }
- Catch(err)
- {
- //
- // If 'MakeSpecifierForPropertyOfSpecifier' fails, we must dispose
- // of selectionSpecifier.
- //
- selectionSpecifier.Dispose();
- Throw(err);
- }
-
- return specifier;
- } // MakeSpecifierForPropertyOfSelection
-
- //----------------------------------------------------------------------------------------
- // GetFinderSelection:
- //
- // This routine asks the Finder for the list of selected items; 'desiredType' specifies
- // the data type that is desired in the result that is sent back; choices include
- // typeObjectSpecifier, typeFSS, and typeAlias.
- //----------------------------------------------------------------------------------------
- TDescriptor GetFinderSelection(DescType desiredType)
- {
- TAEvent ae;
- TAEvent reply;
- TDescriptor target;
- TDescriptor directObjectSpecifier;
- TDescriptor dataDescriptor;
- TDescriptor selectedItems;
- OSErr err = noErr;
-
- Try
- {
- //
- // Get the address of the Finder and make a "Set Data" event
- //
- target = GetAddressOfFinder();
- ae.MakeAppleEvent(kAECoreSuite, kAEGetData, target);
- target.Dispose();
-
- //
- // Make an object specifier for the property we want to set,
- // and put it into the direct object of our event
- //
- directObjectSpecifier = MakeSpecifierForSelection();
- ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
- directObjectSpecifier.Dispose();
-
- //
- // Request FSSpecs back from the Get Data event.
- //
- // The Object Support Library requires that the
- // requested data type be stored in a list of types,
- // so we coerce the 'typeType' descriptor into a list
- // of one descriptor. The Finder does not require
- // this, but some other applications might, since it
- // is part of the OSL spec.
- //
- dataDescriptor.MakeDescType(desiredType);
- dataDescriptor.CoerceInPlace(typeAEList);
- ae.PutDescriptor(keyAERequestedType, dataDescriptor);
- dataDescriptor.Dispose();
-
- //
- // It is generally a bad idea to use kAEWaitReply,
- // because it prevents your application from processing
- // other events. There are a number of potential solutions:
- //
- // Use kAEQueueReply, and process the reply when it is
- // returned from WaitNextEvent. The disadvantage is that
- // the processing of the reply must be done separately
- // from the code that sets up to do the send
- //
- // Provide a filter proc to AESend that processes
- // events while your application is waiting for the reply.
- // The disadvantage of doing this is that the event
- // handling of your application is complicated, and
- // may become nested if events need to be sent to
- // process an incoming message
- //
- // Pass kImmediateTimeout as the timeout value for
- // AESend. When the reply event is accessed, an
- // error is returned if the reply has not yet arrived.
- // This method is best employeed in conjunction with
- // a threads package, so that the thread that sends
- // the message can block until the reply arrives.
- // See the article on Futures by Michael Gough in
- // d e v e l o p issue #7.
- //
- ae.Send(&reply, kAEWaitReply);
-
- //
- // Extract the result from the reply
- //
- selectedItems = reply.GetDescriptor(keyAEResult);
- reply.Dispose();
- }
- Catch(err)
- {
- target.Dispose();
- directObjectSpecifier.Dispose();
- dataDescriptor.Dispose();
- reply.Dispose();
-
- Throw(err);
- }
-
- return selectedItems;
- } // GetFinderSelection
-
- //----------------------------------------------------------------------------------------
- // CountItemsInContainer
- //
- // Returns the number of items of class 'desiredClass' inside the specified
- // container. The target application is specified in the parameter list.
- //----------------------------------------------------------------------------------------
- long CountItemsInContainer(DescType desiredClass, TDescriptor inContainer, TDescriptor target)
- {
- TAEvent ae;
- TAEvent reply;
- TDescriptor keyData;
- OSErr err = noErr;
- long theCount = 0;
-
- Try
- {
- //
- // Make a "Count elements" event
- //
- ae.MakeAppleEvent(kAECoreSuite, kAECountElements, target);
-
- //
- // Put the direct object specifier into the direct object of our event
- //
- ae.PutDescriptor(keyDirectObject, inContainer);
-
- //
- // Specify the class of things we want to count
- //
- keyData.MakeDescType(desiredClass);
- ae.PutDescriptor(keyAEObjectClass, keyData);
- keyData.Dispose();
-
- //
- // Ask the question. kAEWaitReply without filter procs is evil.
- //
- ae.Send(&reply, kAEWaitReply);
-
- //
- // Extract the result out of the reply
- //
- theCount = reply.GetLongParameter(keyAEResult);
- }
- Catch(err)
- {
- //
- // Any of a number of routines that we call above could
- // fail; if they do, we need to dispose of any object
- // that we created.
- //
- ae.Dispose();
- reply.Dispose();
- keyData.Dispose();
-
- Throw(err);
- }
-
- return theCount;
- } // CountItemsInContainer
-
- //----------------------------------------------------------------------------------------
- // MakeSpecifierForAlias
- //----------------------------------------------------------------------------------------
- TDescriptor MakeSpecifierForAlias(Handle aliasHandle)
- {
- TDescriptor specifier;
- TDescriptor keyData;
- TDescriptor nullContainer;
-
- //
- // 'formAlias' is a special key form introduced by the
- // Finder to allow applications to access properties of alias records
- //
- keyData.AdoptHandle(typeAlias, aliasHandle);
- specifier.MakeObjectSpecifier(typeWildCard, nullContainer, formAlias, keyData, false);
-
- return specifier;
- } // MakeSpecifierForAlias
-
- void TrashWindowInformation(Handle aliasToWindowOwner, OpenWindowInfo& windowInfo);
-
- //----------------------------------------------------------------------------------------
- // TrashWindowInformation
- //----------------------------------------------------------------------------------------
- void TrashWindowInformation(Handle aliasToWindowOwner, OpenWindowInfo& windowInfo)
- {
- TAEvent ae;
- TAEvent reply;
- TDescriptor windowOwnerSpecifier;
- TDescriptor windowOfOwnerSpecifier;
- TDescriptor positionOfWindowSpecifier;
- TDescriptor dataDescriptor;
- TDescriptor target;
-
- target = GetAddressOfFinder();
-
- //
- // Make a specifier to the window of the owner
- //
- windowOwnerSpecifier = MakeSpecifierForAlias(aliasToWindowOwner);
- windowOfOwnerSpecifier = MakeSpecifierForPropertyOfSpecifier(windowInfo.fWindowClass,
- windowOwnerSpecifier);
- windowOwnerSpecifier.Dispose();
-
- //
- // Move the window a bit up and left
- //
- OffsetRect(&windowInfo.fWindowBounds, -20, -20);
-
- //
- // Send the Finder a set data on the window's position
- //
- ae.MakeAppleEvent(kAECoreSuite, kAESetData, target);
- positionOfWindowSpecifier = MakeSpecifierForPropertyOfSpecifier(pBounds,
- windowOfOwnerSpecifier);
- ae.PutDescriptor(keyDirectObject, positionOfWindowSpecifier);
- positionOfWindowSpecifier.Dispose();
-
- dataDescriptor.MakeRect(windowInfo.fWindowBounds);
- ae.PutDescriptor(keyAEData, dataDescriptor);
- dataDescriptor.Dispose();
-
- ae.Send(&reply, kAEWaitReply);
-
- //
- // Send the Finder an "close" event
- //
- ae.MakeAppleEvent(kAECoreSuite, kAEClose, target);
- ae.PutDescriptor(keyDirectObject, windowOfOwnerSpecifier);
-
- ae.Send(&reply, kAEWaitReply);
-
- //
- // Throw away that which we do not need
- //
- windowOfOwnerSpecifier.Dispose();
- target.Dispose();
- } // TrashWindowInformation
-
- //----------------------------------------------------------------------------------------
- // SetWindowInformation
- //----------------------------------------------------------------------------------------
- void SetWindowInformation(Handle aliasToWindowOwner, OpenWindowInfo& windowInfo)
- {
- TAEvent ae;
- TAEvent reply;
- TDescriptor windowOwnerSpecifier;
- TDescriptor windowOfOwnerSpecifier;
- TDescriptor positionOfWindowSpecifier;
- TDescriptor dataDescriptor;
- TDescriptor target;
-
- target = GetAddressOfFinder();
-
- //
- // Make a specifier to the window of the owner
- //
- windowOwnerSpecifier = MakeSpecifierForAlias(aliasToWindowOwner);
- windowOfOwnerSpecifier = MakeSpecifierForPropertyOfSpecifier(windowInfo.fWindowClass,
- windowOwnerSpecifier);
- windowOwnerSpecifier.Dispose();
-
- //
- // Send the Finder an "open" event
- //
- ae.MakeAppleEvent(kCoreEventClass, kAEOpen, target);
- ae.PutDescriptor(keyDirectObject, windowOfOwnerSpecifier);
-
- ae.Send(&reply, kAEWaitReply);
-
- //
- // Send the Finder a set data on the window's position
- //
- ae.MakeAppleEvent(kAECoreSuite, kAESetData, target);
- positionOfWindowSpecifier = MakeSpecifierForPropertyOfSpecifier(pBounds,
- windowOfOwnerSpecifier);
- ae.PutDescriptor(keyDirectObject, positionOfWindowSpecifier);
- positionOfWindowSpecifier.Dispose();
-
- dataDescriptor.MakeRect(windowInfo.fWindowBounds);
- ae.PutDescriptor(keyAEData, dataDescriptor);
- dataDescriptor.Dispose();
-
- ae.Send(&reply, kAEWaitReply);
-
- //
- // Throw away that which we do not need
- //
- windowOfOwnerSpecifier.Dispose();
- target.Dispose();
- } // SetWindowInformation
-
- //----------------------------------------------------------------------------------------
- // RestoreAllWindowInformation
- //
- // Assume that the resource fork at the top of the chain contains the saved window
- // positions
- //----------------------------------------------------------------------------------------
- void RestoreAllWindowInformation()
- {
- short numberOfSavedWindows = Count1Resources(kOpenWindowInfoType);
-
- for(short i=1;i<=numberOfSavedWindows;++i)
- {
- OpenWindowInfoHandle infoWindowHandle = (OpenWindowInfoHandle) Get1IndResource(kOpenWindowInfoType, i);
- OpenWindowInfo windowInfo = **infoWindowHandle;
-
- Handle aliasToWindowOwner = Get1Resource(kAliasToWindowOwnerType, windowInfo.fAliasToOwnerID);
- SetWindowInformation(aliasToWindowOwner, windowInfo);
- }
- } // RestoreAllWindowInformation
-
- //----------------------------------------------------------------------------------------
- // SaveWindowInformation
- //
- // Assumes that someone already created a file, and that it's resource fork is at
- // the top of the resource chain.
- //----------------------------------------------------------------------------------------
- void SaveWindowInformation(Handle aliasToWindowOwner, OpenWindowInfo& windowInfo)
- {
- short newID = Unique1ID(kAliasToWindowOwnerType);
-
- HandToHand(&aliasToWindowOwner);
- AddResource(aliasToWindowOwner, kAliasToWindowOwnerType, newID, "\p");
- windowInfo.fAliasToOwnerID = newID;
-
- OpenWindowInfoHandle infoWindowHandle = (OpenWindowInfoHandle) NewHandle(sizeof(OpenWindowInfo));
- FailMemErrorOrNil(infoWindowHandle);
- **infoWindowHandle = windowInfo;
-
- newID = Unique1ID(kOpenWindowInfoType);
- AddResource((Handle)infoWindowHandle, kOpenWindowInfoType, newID, "\p");
- } // SaveWindowInformation
-
- //----------------------------------------------------------------------------------------
- // SaveWindowsAndPositions
- //----------------------------------------------------------------------------------------
- void SaveWindowsAndPositions()
- {
- TDescriptor target;
- TDescriptor nullContainer;
- long openWindows = 0;
- OSErr err = noErr;
-
- Try
- {
- target = GetAddressOfFinder();
-
- //
- // Ask the Finder how many windows are open
- //
- openWindows = CountItemsInContainer(cWindow, nullContainer, target);
-
- //
- // Iterate once per open window
- //
- for(long i=1; i<=openWindows; ++i)
- {
- TDescriptor windowNSpecifier;
- TDescriptor propertySpecifier;
- TDescriptor keyData;
- TDescriptor resultDescriptor;
- TAEvent ae;
- TAEvent reply;
- Handle aliasToWindowOwner = nil;
- DescType windowClass;
- Rect windowBounds;
-
- //
- // If we fail to get information on one window,
- // just skip it and go on to the next
- //
- Try
- {
- //
- // Make an object specifier for the N'th window
- //
- windowNSpecifier = MakeSpecifierForIndexedItem(cWindow, i, nullContainer);
-
- //
- // Get the folder of the open window
- //
- // We are asking for 'item of window i'; in this case, 'item'
- // refers to the item that "owns" the window.
- //
- ae.MakeAppleEvent(kAECoreSuite, kAEGetData, target);
- propertySpecifier = MakeSpecifierForPropertyOfSpecifier(cObject,
- windowNSpecifier);
- ae.PutDescriptor(keyDirectObject, propertySpecifier);
- propertySpecifier.Dispose();
-
- //
- // We are asking for the data as an alias; this might
- // not be possible for some windows (e.g. the "About this
- // Macintosh" window or "Finder Shortcuts"; for these
- // windows, ae.Send will fail.
- //
- keyData.MakeDescType(typeAlias);
- keyData.CoerceInPlace(typeAEList);
- ae.PutDescriptor(keyAERequestedType, keyData);
- keyData.Dispose();
-
- ae.Send(&reply, kAEWaitReply);
-
- resultDescriptor = reply.GetDescriptor(keyAEResult);
- aliasToWindowOwner = resultDescriptor.DataHandle();
- resultDescriptor.MakeNull();
-
- //
- // Get the class of the open window
- //
- ae.MakeAppleEvent(kAECoreSuite, kAEGetData, target);
- propertySpecifier = MakeSpecifierForPropertyOfSpecifier(pClass,
- windowNSpecifier);
- ae.PutDescriptor(keyDirectObject, propertySpecifier);
- propertySpecifier.Dispose();
-
- ae.Send(&reply, kAEWaitReply);
-
- resultDescriptor = reply.GetDescriptor(keyAEResult);
- windowClass = resultDescriptor.GetDescType();
- resultDescriptor.Dispose();
-
- //
- // Get the position of the open window
- //
- ae.MakeAppleEvent(kAECoreSuite, kAEGetData, target);
- propertySpecifier = MakeSpecifierForPropertyOfSpecifier(pBounds,
- windowNSpecifier);
- ae.PutDescriptor(keyDirectObject, propertySpecifier);
- propertySpecifier.Dispose();
-
- ae.Send(&reply, kAEWaitReply);
-
- resultDescriptor = reply.GetDescriptor(keyAEResult);
- windowBounds = resultDescriptor.GetRect();
- resultDescriptor.Dispose();
-
- //
- // Make a window info structure
- //
- OpenWindowInfo theWindowInfo;
- theWindowInfo.fWindowClass = windowClass;
- theWindowInfo.fWindowBounds = windowBounds;
-
- //
- // Save all of that information somewhere
- //
- SaveWindowInformation(aliasToWindowOwner, theWindowInfo);
-
- //
- // Dispose the window specifier and continue
- //
- windowNSpecifier.Dispose();
- }
- Catch(err)
- {
- //
- // Clean up before we go around again
- //
- keyData.Dispose();
- propertySpecifier.Dispose();
- resultDescriptor.Dispose();
- windowNSpecifier.Dispose();
- }
- }
-
- //
- // Done with the target
- //
- target.Dispose();
- }
- Catch(err)
- {
- //
- // Any of a number of routines that we call above could
- // fail; if they do, we need to dispose of any object
- // that we created.
- //
- target.Dispose();
- }
- } // SaveWindowsAndPositions
-
- //----------------------------------------------------------------------------------------
- // UpdateChangedObject:
- //----------------------------------------------------------------------------------------
- void UpdateChangedObject(FSSpec& itemsFSSpec)
- {
- TAEvent ae;
- TAEvent reply;
- TDescriptor target;
- TDescriptor directObjectSpecifier;
- OSErr err = noErr;
-
- Try
- {
- //
- // Get the address of the Finder and make an "Update" event
- //
- target = GetAddressOfFinder();
- ae.MakeAppleEvent(kAEFinderSuite, kAEUpdate, target);
- target.Dispose();
-
- //
- // Most scriptable applications require the direct
- // object of an event to always be an object
- // specifier. The Finder is special, though; it
- // will accept FSSpecs and alias records as well.
- //
- directObjectSpecifier.MakeFSS(itemsFSSpec);
- ae.PutDescriptor(keyDirectObject, directObjectSpecifier);
- directObjectSpecifier.Dispose();
-
- //
- // The reply isn't actuall filled in due to the kAENoReply flag
- //
- ae.Send(&reply, kAENoReply);
- }
- Catch(err)
- {
- //
- // Any of a number of routines that we call above could
- // fail; if they do, we need to dispose of any object
- // that we created.
- //
- target.Dispose();
- directObjectSpecifier.Dispose();
- ae.Dispose();
-
- Throw(err);
- }
- } // UpdateChangedObject
-
-